package com.mrdeer.web.controller.sys;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mrdeer.common.JSONResult;
import com.mrdeer.common.constants.CommonConstant;
import com.mrdeer.common.entity.dto.RoleDTO;
import com.mrdeer.common.entity.sys.Role;
import com.mrdeer.common.entity.sys.RoleDepartment;
import com.mrdeer.common.entity.sys.RolePermission;
import com.mrdeer.common.entity.sys.UserRole;
import com.mrdeer.common.tools.RedisTemplateHelper;
import com.mrdeer.web.service.sys.SysRoleDepartmentService;
import com.mrdeer.web.service.sys.SysRolePermissionService;
import com.mrdeer.web.service.sys.SysRoleService;
import com.mrdeer.web.service.sys.SysUserRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@Api(tags = "角色管理接口")
@RequestMapping("/mrdeer/role")
@Transactional
public class SysRoleController {

    @Resource
    private SysRoleService sysRoleService;

    @Resource
    private SysUserRoleService sysUserRoleService;

    @Resource
    private SysRolePermissionService sysRolePermissionService;

    @Resource
    private SysRoleDepartmentService sysRoleDepartmentService;

    @Resource
    private RedisTemplateHelper redisTemplate;

    @RequestMapping(value = "/getAllList", method = RequestMethod.GET)
    @ApiOperation(value = "获取全部角色")
    public JSONResult getAllRole() {
        return JSONResult.ok(sysRoleService.list());
    }

    @RequestMapping(value = "/getAllByPage", method = RequestMethod.POST)
    @ApiOperation(value = "分页获取角色列表")
    public JSONResult getRoleByPage(@RequestBody RoleDTO roleDTO) {
        Page<Role> roleList = sysRoleService.list(roleDTO);
        for (Role role : roleList.getRecords()) {
            //角色拥有权限
            List<RolePermission> permissions = sysRolePermissionService.findByRoleId(role.getId());
            role.setPermissions(permissions);
            //角色拥有的数据权限
            List<RoleDepartment> departments = sysRoleDepartmentService.findByRoleId(role.getId());
            role.setDepartments(departments);
        }
        return JSONResult.ok(roleList);
    }

    @RequestMapping(value = "/setDefault", method = RequestMethod.POST)
    @ApiOperation(value = "设置或者取消默认角色")
    public JSONResult setDefault(@RequestBody RoleDTO dto) {
        Role role = sysRoleService.getById(dto.getId());
        if (role == null) {
            return JSONResult.errorMsg("角色不存在");
        }
        role.setDefaultRole(dto.getDefaultRole());
        sysRoleService.update(role);
        return JSONResult.ok("设置成功");
    }

    @RequestMapping(value = "/editRolePerm", method = RequestMethod.POST)
    @ApiOperation(value = "编辑角色分配菜单权限")
    public JSONResult editRolePerm(@RequestParam String roleId, @RequestParam(required = false) String permIds) {
        //删除其关联权限
        sysRolePermissionService.deleteByRoleId(roleId);
        String[] permList = permIds.split(",");
        //批量分配新权限
        if (permList != null) {
            List<RolePermission> list = Arrays.asList(permList).stream().map(e -> {
                return new RolePermission().setRoleId(roleId).setPermissionId(e);
            }).collect(Collectors.toList());
            sysRolePermissionService.saveOrUpdateBatch(list);
        }
        //手动批量删除缓存
        redisTemplate.deleteByPattern("user:*");
        redisTemplate.deleteByPattern("userRole:*");
        redisTemplate.deleteByPattern("permission::*");
        return JSONResult.ok(null);
    }

    @RequestMapping(value = "/editRoleDep", method = RequestMethod.POST)
    @ApiOperation(value = "编辑角色分配数据权限")
    public JSONResult editRoleDep(@RequestParam String roleId, @RequestParam Integer dataType, @RequestParam(required = false) String[] depIds) {
        Role r = sysRoleService.getById(roleId);
        r.setDataType(dataType);
        sysRoleService.updateById(r);
        if (CommonConstant.DATA_TYPE_CUSTOM.equals(dataType)) {
            //删除其关联数据权限
            sysRoleDepartmentService.deleteByRoleId(roleId);
            //批量分配新数据权限
            if (depIds != null) {
                List<RoleDepartment> list = Arrays.asList(depIds).stream().map(e -> {
                    return new RoleDepartment().setRoleId(roleId).setDepartmentId(e);
                }).collect(Collectors.toList());
                sysRoleDepartmentService.saveOrUpdateBatch(list);
            }
        }
        //手动删除相关缓存
        redisTemplate.deleteByPattern("department:*");
        redisTemplate.deleteByPattern("userRole:*");
        return JSONResult.ok(null);
    }

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ApiOperation(value = "保存数据")
    public JSONResult save(@RequestBody RoleDTO role) {
        sysRoleService.add(role);
        return JSONResult.ok("保存成功");
    }

    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @ApiOperation(value = "更新数据")
    public JSONResult edit(@RequestBody RoleDTO entity) {
        Role role = sysRoleService.update(entity);
        //手动批量删除缓存
        redisTemplate.deleteByPattern("user:*");
        redisTemplate.deleteByPattern("userRole:*");
        return JSONResult.ok(role);
    }

    @RequestMapping(value = "/delByIds", method = RequestMethod.POST)
    @ApiOperation(value = "批量通过ids删除")
    public JSONResult delByIds(@RequestParam String ids) {
        String[] idList = ids.split(",");
        for (String id : idList) {
            List<UserRole> list = sysUserRoleService.findByRoleId(id);
            if (list != null && list.size() > 0) {
                return JSONResult.errorMsg("删除失败，包含正被用户使用关联的角色");
            }
        }
        for (String id : idList) {
            sysRoleService.removeById(id);
            sysRolePermissionService.remove(new QueryWrapper<RolePermission>().eq("role_id", id));
            sysRoleDepartmentService.remove(new QueryWrapper<RoleDepartment>().eq("role_id", id));
            //TODO:删除流程关联节点
        }
        return JSONResult.ok("批量通过id删除数据成功");
    }
}
